import _ from 'lodash'
import { article, desc, descFunc, section } from './lablog.js'
import {Maybe, map, add, chain, join} from './util.js'

Maybe.prototype.ap = function(otherContainer) {
    return otherContainer.map(this.__value)
}
const m1 = Maybe.of(1)
const m2 = Maybe.of(2)
desc("m1 = Maybe.of(1)")
desc("m2 = Maybe.of(2)")

article("applicative functor test.")
const s1 = section("ap 函数能够将一个 functor 的[函数值]应用到另一个 functor 上面")

s1(() => {
    console.log("add(m1)(m2) =", add(m1)(m2))
    console.log("map(add(m2.join()))(m1) =", map(add(m2.join()))(m1))
    console.log("m1.chain((x) => m2.map(add(x))) = ", m1.chain((x) => m2.map(add(x))))
    console.log("m2.map(add).ap(m1) =", m2.map(add).ap(m1))
})

const s2 = section("applicative functor 是实现了 ap 方法的 pointed functor")
s2(() => {
    desc(`注意 pointed 这个前提。`)
    desc(`F.of(x).map(f) == F.of(f).ap(F.of(x))`)
    desc(`即：map 一个 f 等价于 ap 一个值为 f 的 functor。`)
    console.log(`Maybe.of(1).map(add(2)):`, Maybe.of(1).map(add(2)))
    console.log(`Maybe.of(add(2)).ap(m1)`, Maybe.of(add(2)).ap(m1))
})
/**
 * F.of(x).map(f)
 * = F(x).map(f)
 * = F.of(f(x))
 * = F(f(x))
 * 
 * F.of(f).ap(F.of(x))
 * = F.of(x).map(f)
 * = F.of(f(x))
 * = F(f(x))
 */